package ru.emms.codemeter.metrics;

import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.apache.commons.lang.StringUtils;

import java.util.ArrayList;
import java.util.Collection;

/**
 * User: sasha.kon
 * Date: 11.10.2010
 * <p/>
 * Методы, используемые при расчете метрик.
 */
public class MetricUtils {

    /**
     * Строит список классов, содержащихся в коллекции исходников.
     *
     * @param sources коллекция исходников
     *
     * @return коллекцию классов, содержащихся в исходниках
     */
    public static Collection<PsiClass> getClassesIn(Collection<PsiFile> sources) {
        Collection<PsiClass> classCollection = new ArrayList<PsiClass>();
        for (PsiElement source : sources) {
            findClasses(source, classCollection);
        }
        return classCollection;
    }

    /**
     * Построить список классов, содержащихся в исходнике, включая вложенные классы,
     * перечисления (enum), интерфейсы.
     * Метод рекурсивно вызывает себя для поиска классов в древоводной структуре исходника.
     *
     * @param source                исходник
     * @param outputClassCollection коллекция, куда записываются классы, содержащиеся в исходнике.
     *                              <b>Выходной параметр.</b>
     */
    public static void findClasses(PsiElement source, Collection<PsiClass> outputClassCollection) {
        for (PsiElement child : source.getChildren()) {
            if(child instanceof PsiClass) {
                outputClassCollection.add((PsiClass)child);
            }
            findClasses(child, outputClassCollection);
        }
    }

    /**
     * @param source исходник
     *
     * @return Число строк в исходнике
     */
    public static int linesCount(String source) {
        return StringUtils.countMatches(source, "\n") + 1;
    }
}
